package xm.com.handlertest;

import android.os.Build;
import android.os.Looper;
import android.os.MessageQueue;
import android.support.annotation.RequiresApi;

import java.util.concurrent.LinkedTransferQueue;


public class TestThreadMsg4 {
    public static Looper mainLooper;

    public static void main(String[] args){
        Looper.prepare();
        //myLooper方法在哪个线程里调用就会返回该线程对应的Looper对象
        mainLooper = Looper.myLooper();

        Thread1 t1 = new Thread1();
        t1.start();

        Looper.loop();//阻塞式,死循环遍历消息列表

    }

    /**
     * 消息实体类,主要职责:
     *  1.承载消息内容
     */
    static class Message {
        public int what;
        public Object obj;
    }

    /**
     * 模拟Looper，主要职责:
     *  1.创建管理消息队列
     *  2.不断死循环取出消息队列里的消息
     *  3.处理消息（后续交给Handler处理）
     *  说明：Looper用静态prepare()方法实例化自己，每个线程只能实例化一个Looper对象
     *  Looper的myLooper()方法，在哪个线程调用就返回哪个线程的Looper对象(通过ThreadLocal实现)
     */
    static class Looper{
        //ThreadLocal用于保存某个线程共享变量:对于同一个static ThreadLocal,不同线程只能从中get,set,remove自己的变量,而不会影响其他线程的变量
        static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
        LinkedTransferQueue mQueue;//阻塞式消息队列,每一个线程对应一个消息队列

        private Looper(){
            this.mQueue = new LinkedTransferQueue();//初始化阻塞式消息队列
        }

        /**
         * 初始化Looper,并放到线程变量里,
         * 这里做了限制，每个线程只能有一个Looper对象,因为是死循环多个也无意义
         */
        public static void prepare() {
            if (sThreadLocal.get() != null) {
                throw new RuntimeException("Only one Looper may be created per thread");
            }
            sThreadLocal.set(new Looper());
        }

        /**
         * 从线程变量里取出,当前线程对应的Looper
         * @return
         */
        public static Looper myLooper() {
            return sThreadLocal.get();
        }

        /**
         * 取出当前线程里的Looperd对象开始死循环遍历消息队列
         */
        public static void loop(){
            final Looper me = myLooper();
            //模拟LOOP的循环方法
            for (;;) {
                Message msg = null;
                try {
                    msg = (Message) me.mQueue.take();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("主线程:"+Thread.currentThread().getId()+"  收到:"+msg.obj);
                if (msg.what == 1){
                    System.out.println("主线程:"+Thread.currentThread().getId()+"  do work!");
                    System.out.println("");
                    System.out.println("");
                }
            }
        }

        public LinkedTransferQueue getQueue() {
            return mQueue;
        }
    }


    static class Thread1 extends Thread{
        @Override
        public void run() {
            super.run();
            for (;;) {
                try {
                    Message msg = new Message();
                    msg.what = 1;
                    msg.obj = "主线程去更新UI吧";
                    System.out.println("子线程:"+Thread.currentThread().getId()+"  发送:"+msg.obj);
                    mainLooper.getQueue().put(msg);//向主线程的Looper的消息队列里添加消息
                    Thread.sleep(5000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

}
